package com.gee.spring.cloud.aerospace.simulate.mgt.controller;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gee.cloud.common.core.api.domain.result.ApiResult;
import com.gee.cloud.starter.web.util.excel.ExcelUtil;
import com.gee.spring.cloud.aerospace.simulate.mgt.controller.req.page.SatelliteTelemetryParamPage;
import com.gee.spring.cloud.aerospace.simulate.mgt.entity.SatelliteTelemetryParam;
import com.gee.spring.cloud.aerospace.simulate.mgt.service.SatelliteTelemetryParamService;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Objects;
import java.util.Optional;

/**
 *
 * @author gee
 * @since 2024-07-10
 */
@RestController
@Tag(name = "卫星遥测参数")
@ApiSupport(author = "gee", order = 1)
@RequestMapping("/satelliteTelemetryParam")
public class SatelliteTelemetryParamController {
    private final Logger logger = LoggerFactory.getLogger(SatelliteTelemetryParamController.class);

    @Autowired
    private SatelliteTelemetryParamService satelliteTelemetryParamService;

    @PostMapping("/add")
    @Operation(summary = "新增单条卫星遥测参数")
    @ApiOperationSupport(order = 1, author = "gee")
    public ApiResult<SatelliteTelemetryParam> add(@Validated @RequestBody SatelliteTelemetryParam satelliteTelemetryParam){
        satelliteTelemetryParamService.save(satelliteTelemetryParam);
        return ApiResult.success(satelliteTelemetryParam);
    }


    @PutMapping("/updateById")
    @Operation(summary = "根据id更新单条卫星遥测参数记录")
    @ApiOperationSupport(order = 2, author = "gee")
    public ApiResult<Object> updateById(@Validated @RequestBody SatelliteTelemetryParam satelliteTelemetryParam){
        satelliteTelemetryParamService.updateById(satelliteTelemetryParam);
        return ApiResult.success();
    }

    @DeleteMapping("/deleteById/{id}")
    @Operation(summary = "根据id删除单条卫星遥测参数记录")
    @ApiOperationSupport(order = 3, author = "gee")
    public ApiResult<Object> deleteById(@PathVariable Long id){
        satelliteTelemetryParamService.removeById(id);
        return ApiResult.success();
    }

    @DeleteMapping("/batchDelByIds/{ids}")
    @Operation(summary = "根据ids批量删除卫星遥测参数记录")
    @ApiOperationSupport(order = 4, author = "gee")
    public ApiResult<Object> removeByIds( @PathVariable ArrayList<Long> ids){
        satelliteTelemetryParamService.removeByIds(ids);
        return ApiResult.success();
    }

    @GetMapping("/downloadTemplate")
    @Operation(summary = "下载模板")
    @ApiOperationSupport(order = 5, author = "gee")
    public void downloadTemplate(HttpServletResponse response) {
        String excelName = SatelliteTelemetryParam.class.getAnnotation(Schema.class).description();
        ExcelUtil.write(excelName, response)
            .sheet(excelName, SatelliteTelemetryParam.class)
            .finish();
    }

    @PostMapping("/import")
    @Operation(summary = "导入卫星遥测参数")
    @ApiOperationSupport(order = 6, author = "gee")
    public ApiResult<Object> importSatelliteTelemetryParam(@RequestPart MultipartFile file) throws IOException {
        ExcelUtil.read(file.getInputStream())
            .sheet(SatelliteTelemetryParam.class.getAnnotation(Schema.class).description(), SatelliteTelemetryParam.class)
            .readBatchContinuousLy(dataList -> {
                dataList.forEach(instance -> {
                });
                satelliteTelemetryParamService.saveBatch(dataList);
            });
        return ApiResult.success();
    }

    @PostMapping(value = "/export", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
    @Operation(summary = "导出卫星遥测参数")
    @ApiOperationSupport(order = 7, ignoreParameters = {"countId", "maxLimit", "optimizeCountSql", "optimizeJoinOfCountSql",
            "orders", "pages", "records", "searchCount", "total", "current", "size"}, author = "gee")
    public void export(@RequestBody SatelliteTelemetryParamPage page, HttpServletResponse response) {
        String excelName = SatelliteTelemetryParam.class.getAnnotation(Schema.class).description();
        LambdaQueryWrapper<SatelliteTelemetryParam> pageQueryWrapper = getPageQueryWrapper(page);
        pageQueryWrapper.orderByAsc(SatelliteTelemetryParam::getId);
        ExcelUtil.write(excelName, response)
            .sheet(excelName, SatelliteTelemetryParam.class)
            .writeBatchContinuousLy(
                () -> satelliteTelemetryParamService.count(pageQueryWrapper),
                ((currentPage, batchSize) -> {
                    String lastSql = String.format("limit %s, %s", currentPage, batchSize);
                    pageQueryWrapper.last(lastSql);
                    return satelliteTelemetryParamService.list(pageQueryWrapper);
                })
            )
            .finish();
    }

    @GetMapping("/getById/{id}")
    @Operation(summary = "根据id查询单条卫星遥测参数记录")
    @ApiOperationSupport(order = 101, author = "gee")
    public ApiResult<SatelliteTelemetryParam> getById(@PathVariable("id") Long id){
        SatelliteTelemetryParam satelliteTelemetryParam = satelliteTelemetryParamService.getById(id);
        return ApiResult.success(satelliteTelemetryParam);
    }

    @GetMapping("/getBySateIdAndParamCode/{sateId}/{paramCode}")
    @Operation(summary = "根据卫星id和遥测参数代号查询单条卫星遥测参数记录")
    @ApiOperationSupport(order = 102, author = "gee")
    public ApiResult<SatelliteTelemetryParam> getBySateIdAnd(@PathVariable("sateId") Long sateId,
                                                        @PathVariable("paramCode") Long paramCode){
        LambdaQueryWrapper<SatelliteTelemetryParam> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SatelliteTelemetryParam::getSateId, sateId)
                    .eq(SatelliteTelemetryParam::getParamCode, paramCode);
        SatelliteTelemetryParam satelliteTelemetryParam = satelliteTelemetryParamService.getOne(queryWrapper);
        return ApiResult.success(satelliteTelemetryParam);
    }

    @PostMapping("/pagination")
    @Operation(summary = "分页查询卫星遥测参数信息记录")
    @ApiOperationSupport(order = 103, ignoreParameters = {"page.countId", "page.maxLimit", "page.optimizeCountSql", "page.optimizeJoinOfCountSql",
            "page.orders", "page.pages", "page.records", "page.searchCount", "page.total"}, author = "gee")
    public ApiResult<Page<SatelliteTelemetryParam>> pagination(@Validated @RequestBody SatelliteTelemetryParamPage page){
        LambdaQueryWrapper<SatelliteTelemetryParam> pageQueryWrapper = getPageQueryWrapper(page);
        pageQueryWrapper.orderByDesc(SatelliteTelemetryParam::getId);
        Page<SatelliteTelemetryParam> resultPage = satelliteTelemetryParamService.page(page, pageQueryWrapper);
        return ApiResult.success(resultPage);
    }

    private LambdaQueryWrapper<SatelliteTelemetryParam> getPageQueryWrapper(SatelliteTelemetryParamPage page){
        LambdaQueryWrapper<SatelliteTelemetryParam> wrapper = new LambdaQueryWrapper<>();
        Optional.ofNullable(page).ifPresent(s -> {
            if (StringUtils.isNotEmpty(s.getParamCode())){
                wrapper.like(SatelliteTelemetryParam::getParamCode, s.getParamCode());
            }
            if (StringUtils.isNotEmpty(s.getParamName())){
                wrapper.like(SatelliteTelemetryParam::getParamName, s.getParamName());
            }
            if (Objects.nonNull(s.getSateId())){
                wrapper.eq(SatelliteTelemetryParam::getSateId, s.getSateId());
            }
            if (Objects.nonNull(s.getPackageId())){
                wrapper.eq(SatelliteTelemetryParam::getPackageId, s.getPackageId());
            }
            if (!CollectionUtils.isEmpty(s.getIdList())){
                wrapper.in(SatelliteTelemetryParam::getId, s.getIdList());
            }
        });
        return wrapper;
    }
}